package com.cn.algorithm01;

/**
 * @author hels
 * @version 1.0
 * @date 2021/10/15 12:01
 * 使用位运算实现：加减乘除
 * // 测试链接：https://leetcode.com/problems/divide-two-integers
 */
public class Code14_BitAddMinusMultiDiv {
    // 加法
    public static int add(int a, int b) {
        int sum = a;
        while (b != 0) {
            sum = a ^ b;
            b = (a & b) << 1;
            a = sum;
        }
        return sum;
    }

    // 求相反数
    public static int negNum (int n) {
        return add(~n, 1);
    }

    // 判断是否负数
    public static boolean isNeg(int n) {
        return n < 0;
    }

    // 减法
    public static int minus(int a, int b) {
        return add(a, negNum(b));
    }

    // 乘法(通过乘法分配律可以解释）
    public static int multi(int a, int b) {
        int res = 0;
        while (b != 0) {
            if ((b & 1) != 0) {
                res = add(res, a);
            }
            b >>>= 1;
            a <<= 1;
        }

        return res;
    }

    // 除法(Integer.MIN_VALUE没有绝对值，其相反数还是本身
    public static int div(int a, int b) {
        int x = isNeg(a) ? negNum(a) : a;
        int y = isNeg(b) ? negNum(b) : b;
        int res = 0;

        for (int i = 30; i >= 0;i = minus(i, 1)) {
            if ((x >> i) >= y) {
                res = res | (1 << i);
                x = minus(x, (y << i));
            }
        }

        return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
    }

    // 排除int最小值影响
    public static int divde(int a, int b) {
        if (a == Integer.MIN_VALUE && b == Integer.MIN_VALUE) {
            return 1;
        } else if (b == Integer.MIN_VALUE) {
            return 0;
        } else if (a == Integer.MIN_VALUE) {
            if (b == negNum(1)) {
                return Integer.MAX_VALUE;
            } else {
                int res = div(add(a, 1), b);
                return add(res, div(minus(a, multi(res, b)), b));
            }
        } else {
            return div(a, b);
        }
    }



    public static void main(String[] args) {
        //System.out.println(multi(8, -6));
        System.out.println(divde(Integer.MIN_VALUE,5));
        System.out.println(Integer.MIN_VALUE/5);

    }


}
